﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Behaviours.Entities
{
  [DebuggerTypeProxy(typeof (HashSetDebugView<>))]
  [DebuggerDisplay("Count = {Count}")]
  public class ArrayPool<T> where T : IIndex
  {
    internal T[] items = new T[256];
    internal bool[] buckets = new bool[256];
    private int index;
    private int count;

    public T this[int index]
    {
      get => this.items[index];
      set => this.items[index] = value;
    }

    public int Count => this.count;

    public void Add(T item)
    {
      lock (this)
      {
        if (item.Index != -1 && !this.buckets[item.Index])
        {
          this.items[item.Index] = item;
          this.buckets[item.Index] = true;
        }
        else
        {
          this.items[this.index] = item;
          this.buckets[this.index] = true;
          item.Index = this.index;
          ++this.index;
          if (this.index >= this.items.Length)
          {
            T[] objArray = new T[this.items.Length * 2];
            bool[] flagArray = new bool[this.items.Length * 2];
            Array.Copy(this.items, 0, objArray, 0, this.items.Length);
            Array.Copy(this.buckets, 0, flagArray, 0, this.buckets.Length);
            this.items = objArray;
            this.buckets = flagArray;
          }
          this.count = this.index;
        }
      }
    }

    public void Remove(T item)
    {
      lock (this)
      {
        this.items[item.Index] = default (T);
        this.buckets[item.Index] = false;
      }
    }

    public T[] ToArray()
    {
      List<T> objList = new List<T>();
      for (int index = 0; index < this.items.Length; ++index)
      {
        if (this.buckets[index])
          objList.Add(this.items[index]);
      }
      return objList.ToArray();
    }
  }
}
